package com.fcscs.cservice.client.main.configuration.reservation;

import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.FieldEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.form.AdapterField;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.Validator;
import com.fcscs.core.gwt.common.AsyncCallbackListener.AsyncBackgroundCallbackListener;
import com.fcscs.core.gwt.common.CoreConstants;
import com.fcscs.core.gwt.common.CoreConstants.ValidationListener;
import com.fcscs.core.gwt.common.CoreEnums.SubmitType;
import com.fcscs.core.gwt.common.FormSubmitListener;
import com.fcscs.core.gwt.common.ui.BaseFormDialog;
import com.fcscs.core.gwt.common.ui.FcsFields.FormButton;
import com.fcscs.core.gwt.common.ui.FcsFormPanel;
import com.fcscs.cservice.client.common.controller.CServiceCommonServiceController;
import com.fcscs.cservice.client.common.model.configuration.reservation.PropertyIdNameModelData;
import com.fcscs.cservice.domain.PaymentMethod;
import com.fcscs.share.gwt.common.LocaleHelper;
import com.fcscs.share.gwt.common.ShareGWTConstants;

public class PayTypeDialog extends BaseFormDialog<PaymentMethod> implements
		FormSubmitListener<PaymentMethod> {
	private MyFormPanel formPanel;
	private FormSubmitListener<PaymentMethod> listener;
	private static PayTypeDialog INSTANCE;
	private boolean isAdd;
	private PropertyIdNameModelData currentProperty;
	private TextField<String> nameField;
	private TextField<String> nameSecField;
	private PaymentMethod currentPayMethod;
	
	public static PayTypeDialog getInstance(
			FormSubmitListener<PaymentMethod> listener,
			boolean isAdd, PropertyIdNameModelData currentProperty){
		if(INSTANCE == null){
			INSTANCE = new PayTypeDialog();
		}
		INSTANCE.isAdd = isAdd;
		INSTANCE.listener = listener;
		INSTANCE.currentProperty = currentProperty;
		INSTANCE.setTitle(isAdd);
		return INSTANCE;
	}
	
	private void setTitle(final boolean isAdd) {
		if(isAdd){
			//true is add
			setHeading(CoreConstants.CORE_MESSAGES.operation(CoreConstants.CORE_CONSTANTS.add(),
					ShareGWTConstants.SHARE_GWT_CONSTANTS.paymentType()));
		}else{
			//false is update
			setHeading(CoreConstants.CORE_MESSAGES.operation(CoreConstants.CORE_CONSTANTS.edit(),
					ShareGWTConstants.SHARE_GWT_CONSTANTS.paymentType()));
		}
	}

	private PayTypeDialog() {
		formPanel = new MyFormPanel(this);
		formPanel.setId("PayTypeDialog_formPanel");
		add(formPanel);
		setSize(400,180);
	}
	
	private class MyFormPanel extends FcsFormPanel<PaymentMethod>{
		private AdapterField propAdpField;
		private Label propLabel;
		private FormButton sbtn;
		
		private Validator nameValidator = new Validator() {
			@Override
			public String validate(Field<?> field, final String value) {
				if(value == null){
					return CoreConstants.CORE_CONSTANTS.requiredField();
				}else if(value.trim().isEmpty()){
					return ShareGWTConstants.SHARE_GWT_CONSTANTS.cannotEmpty();
				}else if(value.trim().length()>20){
					return ShareGWTConstants.SHARE_GWT_MESSAGES.outOfLength(CoreConstants.CORE_CONSTANTS.name(), 20);
				}

				return null;
			}
		};
		
		private Validator nameSecValidator = new Validator() {
			@Override
			public String validate(Field<?> field, final String value) {
				if(value != null && !value.trim().isEmpty() && value.trim().length() > 20){
					return ShareGWTConstants.SHARE_GWT_MESSAGES.outOfLength(CoreConstants.CORE_CONSTANTS.secondaryName(), 20);
				}

				return null;
			}
		};
		
		@Override
		protected void delayValidation(final ValidationListener l) {
			isPayMethodTaken(l);
		}

		protected MyFormPanel(FormSubmitListener<PaymentMethod> l) {
			super(l);
			setHeaderVisible(false);
			setLabelWidth(120);
			
			propLabel = new Label();
			propLabel.setId("PayTypeDialog_propLabel");

			propAdpField = new AdapterField(propLabel);
			propAdpField.setId("PayTypeDialog_propAdpField");
			propAdpField.setFieldLabel(CoreConstants.CORE_CONSTANTS.property());
//			propAdpField.setStyleAttribute(EConnectConstants.CSS_VERTICAL_ALIGN,EConnectConstants.CSS_SUB);
			add(propAdpField);

			nameField = new TextField<String>();
			nameField.setId("PayTypeDialog_Name_textField");
			nameField.setLabelSeparator(CoreConstants.REQURIED_FIELD_LABEL);
			nameField.setFieldLabel(CoreConstants.CORE_CONSTANTS.name());
			nameField.setAllowBlank(false);
			nameField.setValidator(nameValidator);
			nameField.addListener(Events.OnBlur,new Listener<FieldEvent>() {
				@Override
				public void handleEvent(FieldEvent be) {
					String value = nameField.getValue();
					if(value == null){
						nameField.forceInvalid(CoreConstants.CORE_CONSTANTS.requiredField());
						return;
					}else if(value.trim().isEmpty()){
						nameField.forceInvalid(ShareGWTConstants.SHARE_GWT_CONSTANTS.cannotEmpty());
						return;
					}else if(value.trim().length()>20){
						nameField.forceInvalid(ShareGWTConstants.SHARE_GWT_MESSAGES.outOfLength(CoreConstants.CORE_CONSTANTS.name(), 20));
						return;
					}
					isPayMethodTaken(null);
				}
			});
			add(nameField);
			
			nameSecField = new TextField<String>();
			nameSecField.setId("PayTypeDialog_nameSecField_textField");
			nameSecField.setFieldLabel(CoreConstants.CORE_CONSTANTS.secondaryName());
			nameSecField.setValidator(nameSecValidator);
			nameSecField.addListener(Events.OnBlur,new Listener<FieldEvent>() {
				@Override
				public void handleEvent(FieldEvent be) {
					String value = nameSecField.getValue();
					if(value != null && !value.trim().isEmpty() && value.trim().length() > 20){
						nameSecField.forceInvalid(ShareGWTConstants.SHARE_GWT_MESSAGES.outOfLength(CoreConstants.CORE_CONSTANTS.secondaryName(), 20));
						return;
					}else{
						nameSecField.clearInvalid();
						return;
					}
				}
			});
			add(nameSecField);
			
			sbtn = new FormButton(CoreConstants.CORE_CONSTANTS.save());
			sbtn.setId("PayTypeDialog_Save_button");
			sbtn.addSelectionListener(new SelectionListener<ButtonEvent>() {
				@Override
				public void componentSelected(ButtonEvent ce) {
					isValid(new ValidationListener() {

						@Override
						public void onValidate(boolean good) {
							if(good){
								submit(SubmitType.DEFAULT);
								sbtn.removeStyleName(CoreConstants.CSS_FORM_BUTTON_FOCUS);
							}
						}
					});
				}
			});
			getButtonBar().add(sbtn);

			// cancel button
			final FormButton cbtn = new FormButton(CoreConstants.CORE_CONSTANTS.cancel());
			cbtn.setId("PayTypeDialog_Cancel_button");
			cbtn.addSelectionListener(new SelectionListener<ButtonEvent>() {
				@Override
				public void componentSelected(ButtonEvent ce) {
					PayTypeDialog.this.hide();
					cbtn.removeStyleName(CoreConstants.CSS_FORM_BUTTON_FOCUS);
				}
			});
			getButtonBar().add(cbtn);
		}

		@Override
		public void updateForm(PaymentMethod entity) {
			nameField.clear();
			nameSecField.clear();
			currentPayMethod = entity;
			propLabel.setText(LocaleHelper.getName(currentProperty.getEntity().getNameSecLang(), currentProperty.getEntity().getName()));
			if(!isAdd){
				nameField.setValue(entity.getMethod());
				nameSecField.setValue(entity.getMethodSecLang());
			}
		}

		@Override
		public void populateEntity(PaymentMethod entity) {
			entity.setMethod(nameField.getValue());
			if (nameSecField.getValue() != null) {
				entity.setMethodSecLang(nameSecField.getValue().trim());
			}else{
				entity.setMethodSecLang(null);
			}
			entity.setPropertyId(currentProperty.getEntity().getId());
		}

		@Override
		public void setFocus() {
			nameField.focus();			
		}
		
		private void isPayMethodTaken(final ValidationListener l){
			CServiceCommonServiceController.getINSTANCE().isPayMethodTaken(
				currentProperty.getEntity().getId(), 
				nameField.getValue().trim(), 
				isAdd ? null : currentPayMethod.getId(), 
				new AsyncBackgroundCallbackListener<Boolean>(){
					@Override
					public void onFailure(Throwable caught) {
						MessageBox.alert(CoreConstants.CORE_MESSAGES.operation(CoreConstants.CORE_CONSTANTS.system(), ShareGWTConstants.SHARE_GWT_CONSTANTS.error()),
								CoreConstants.CORE_CONSTANTS.systemError(), null);
					}

					@Override
					public void onSuccess(Boolean result) {
						if(result){
							nameField.forceInvalid(ShareGWTConstants.SHARE_GWT_MESSAGES.isTaken(nameField.getValue().trim()));
						}else{
							nameField.clearInvalid();
						}
						if(l!=null){
							l.onValidate(!result);
						}
					}

					@Override
					public void onLogin(String username) {
						CServiceCommonServiceController.getINSTANCE().isPayMethodTaken(
								currentProperty.getEntity().getId(), 
								nameField.getValue().trim(), 
								isAdd ? null : currentPayMethod.getId(),this);
					}

					@Override
					public void onPause() {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void onResume() {
						// TODO Auto-generated method stub
						
					}
					
				});
		}
	}
	@Override
	public void formSubmitCallBack(FcsFormPanel<PaymentMethod> form,
			SubmitType submitType) {
		if(listener!=null){
			listener.formSubmitCallBack(form, submitType);
		}
	}

	@Override
	protected FcsFormPanel<PaymentMethod> getFormPanel() {
		return formPanel;
	}

	@Override
	public void hide() {
		super.hide();
	}
}
